package com.ruoyi.system.service.impl;

import com.ruoyi.system.api.domain.MaterialInfojk;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.service.IMaterialInfojkService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.ReentrantLock;

public class InsertInfoTask<T> implements Runnable {
    @Autowired
    private IMaterialInfojkService infojkService;
    private final BlockingQueue<T> queue;
    private final Boolean[] endFlag;
    private final List<Integer> num;
    private Boolean isUpdateSupport;
    private SysUser user;
    private String fz;
    private String result;

    public InsertInfoTask(BlockingQueue<T> queue, Boolean[] endFlag, List<Integer> num,
                          IMaterialInfojkService infojkService, Boolean isUpdateSupport, SysUser user, String fz) {
        this.queue = queue;
        this.endFlag = endFlag;
        this.num = num;
        this.infojkService = infojkService;
        this.isUpdateSupport = isUpdateSupport;
        this.user = user;
        this.fz = fz;
    }

    @Override
    public void run() {
        List<T> list = new ArrayList<T>(1000);
        final ReentrantLock lock = new ReentrantLock();
        final int[] a = {0, 0, 0, 0};
        while (endFlag[0] == false) {
            a[0]++;
            if (queue.isEmpty()) {
                try {
                    Thread.sleep(500);
                }catch (InterruptedException e) {}
                continue;
            }
            while (!queue.isEmpty()) {
                lock.lock();
                list.clear();
                a[1]++;
                if (endFlag[0]==false && queue.size()>1000 && queue.size()<10000) {
                    try {
                        Thread.sleep(100);
                    }catch (InterruptedException e) {}
                    continue;
                }
                // 出栈
                queue.drainTo(list, 20000);

                //分批处理
                if (null != list && list.size() > 0) {
                    a[2]++;
                    int pointsDataLimit = 20000;//限制条数
                    Integer size = list.size();
                    a[3] += size;

                    num.add(size);//统计数量
                    //判断是否有必要分批
                    if (pointsDataLimit < size) {
                        int part = size / pointsDataLimit;//分批数
                        for (int i = 0; i < part; i++) {
                            //1000条
                            List<T> listPage = list.subList(0, pointsDataLimit);
                            this.result = infojkService.importInfo((List<MaterialInfojk>) listPage, isUpdateSupport, user, fz);
                            //剔除
                            list.subList(0, pointsDataLimit).clear();
                        }
                        if (!list.isEmpty()) {
                            //表示最后剩下的数据
                            this.result = infojkService.importInfo((List<MaterialInfojk>) list, isUpdateSupport, user, fz);
                        }
                    } else {
                        this.result = infojkService.importInfo((List<MaterialInfojk>) list, isUpdateSupport, user, fz);
                    }
                } // end if

                if (queue.isEmpty()) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                lock.unlock();
                throw new RuntimeException(this.result);
            }
        }
    }
}
